package binPack.binaryTree
{
	import flash.display.Bitmap;
	import flash.geom.Rectangle;

	/**
	 * sprite packer
	 * @author jakesgordon
	 * @see https://github.com/jakesgordon/bin-packing/blob/master/js/packer.js
	 */	
	public class BinaryTreeBinPacker
	{
		private var binWidth:int;
		private var binHeight:int;
		private var x:int;
		private var y:int;
		private var root:BNode;
		public function BinaryTreeBinPacker(w:int, h:int)
		{
			init(w,h);
		}
		
		public function init(w:int, h:int):void{
			binWidth = w;
			binHeight = h;
			this.root = new BNode(0,0,w,h);
		}
		
		public function fit(images:Vector.<Bitmap>):void{
			var n:int;
			var node:BNode;
			var image:Bitmap;
			var num:int = images.length;
			var fit:BNode;
			images.sort(function(item0:Bitmap, item1:Bitmap):int{
				if( item0.width > item1.width){
					return -1;
				}
				return 1;
			});
			for(n=0; n < num; n++){
				image = images[n];
				node = this.findNode(this.root, image.width, image.height);
				if (node != null){
					fit = this.splitNode(node, image.width, image.height);
					image.x = fit.x;
					image.y = fit.y;
				}
			}
		}
		
		public function findNode(troot:BNode, w:int, h:int):BNode {
			if (troot.used)
				return this.findNode(troot.rightNode, w, h) || this.findNode(troot.downNode, w, h);
			else if ((w <= troot.width) && (h <= troot.height))
				return troot;
			else
				return null;
		}
		
		public function splitNode(node:BNode, w:int, h:int):BNode {
			node.used = true;
			node.downNode  = new BNode( node.x, node.y + h, node.width, node.height - h );
			node.rightNode =  new BNode(node.x + w, node.y, node.width - w,  h );
			return node;
		}
	}
}